package com.xiaoma.lock.condition;


import java.util.PriorityQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducterComsumer {

  private int queueSize = 1000000;
  private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);
  private Lock lock = new ReentrantLock();
  private Condition product = lock.newCondition();
  private Condition consumer = lock.newCondition();

  public static void main(String[] args) throws InterruptedException {
    ProducterComsumer test = new ProducterComsumer();
    Producer producer = test.new Producer();
    Consumer consumer = test.new Consumer();
    producer.start();
    consumer.start();
//    Thread.sleep(0);
//    producer.interrupt();
//    consumer.interrupt();
  }

  class Consumer extends Thread {

    @Override
    public void run() {
      consume();
    }

    volatile boolean flag = true;

    private void consume() {
      while (true) {
        lock.lock();
        try {
          while (queue.isEmpty()) {
            try {
              System.out.println("获取等待");
              consumer.await();
            } catch (InterruptedException e) {
              flag = false;
            }
          }
          Thread.sleep(500);
          queue.poll(); //每次移走队首元素
          product.signal();//唤醒队列中的阻塞线程，从源码可以看出，如果firstWaiter是null则不做任何操作
          System.out.println(Thread.currentThread().getName()+"从队列取走一个元素，队列个数"+queue.size());
        } catch (InterruptedException e) {
          e.printStackTrace();
        } finally {
          lock.unlock();
        }
      }
    }
  }

  class Producer extends Thread {
    volatile boolean flag = true;

    @Override
    public void run() {
      produce();
    }

    private void produce() {

      while (true) {
        lock.lock();
        try {
          while (queue.size() == queueSize) {
            try {
              System.out.println("插入等待");
              product.await();
            } catch (InterruptedException e) {
              flag = false;
            }
          }

          Thread.sleep(500);
          queue.offer(1);        //每次插入一个元素
          consumer.signal();
          System.out.println(Thread.currentThread().getName()+"向队列中插入一个元素，队列个数：" + (queue.size()));
        } catch (InterruptedException e) {
          e.printStackTrace();
        } finally {
          lock.unlock();
        }
      }
    }
  }
}
